/*
 * create:2016年4月24日 上午12:02:48
 * author:wangds  
 */
package com.cxkj.shop.utils;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.cxkj.shop.LevelUpCardHasBeenUsedException;
import com.cxkj.shop.LevelUpCardIsNotNeedBuyExcption;
import com.cxkj.shop.LevelUpCardIsNotNeedException;
import com.cxkj.shop.NotHaveTargetLevelUpCardException;
import com.cxkj.shop.model.order.DefaultOrder;
import com.cxkj.shop.model.user.DefaultPostAddress;
import com.cxkj.shop.model.user.DefaultWxUserIntAsset;
import com.cxkj.shop.model.user.GegewuUser;
import com.cxkj.shop.model.user.User;

/**
 * .
 * @author wangds
 *
 */
public final class UserUtils extends AbstractBusinessUtils{


  @SuppressWarnings("unchecked")
  public static <U extends User> U createAndSaveNewUserByOpenId(String openId) {
    DefaultWxUserIntAsset user = new DefaultWxUserIntAsset();
    user.setOpenId(openId);
    if( execUpdateSql("insNewUser", user)){
      return (U)user;
    }else{
      return null;
    }
  }

  public static <U extends User> boolean deleteUser(U user) {
    if (user == null) {
      return true;
    }
    if (StringUtils.isBlank(user.getUserId())) {
      return true;
    }
    return execUpdateSql("delUser", user);
  }

  public static <U extends User> U selectUserByOpenId(String openId) {
    U res = execSelectOne("selUserById", openId);
    if(res==null){
      return res;
    }
    if(res.getStatus()==1){
      res.setFavor(DictUtils.loadVipFavor());
    }
    return res;
  }

  
  public static int USER_STATUS_VIP=1;
  public static int USER_STATUS_NORMAL=0;
  public static <U extends User> U setUserStatusAsNormal(U user) {
    return setUserStatus(user,USER_STATUS_NORMAL);
  }
  
  public static <U extends User> U setUserStatusAsVIP(U user) {
    return setUserStatus(user,USER_STATUS_VIP);
  }
  
  private static <U extends User> U setUserStatus(U user, int status) {
    U res = user;
    // 
    if (user == null) {
      return res;
    }
    if (StringUtils.isBlank(user.getUserId())) {
      return res;
    }
    int old_status = user.getStatus();
    boolean exec = false;
    try {
      user.setStatus(status);
      exec = execUpdateSql("updUserStatusByUserIdWithMap",res);
    } finally {
      if (!exec) {
        user.setStatus(old_status);
      }
    }
    return user;
  }
  
  public static final int USER_LEVEL_0 = 0;
  public static final int USER_LEVEL_1 = 1;
  public static final int USER_LEVEL_2 = 2;
  public static final int USER_LEVEL_3 = 3;
  public static final int USER_LEVEL_4 = 4;
  
  public static <U extends User> U userLevelUp(U user){
    return setUserLevel(user, user.getLevel()+1);
  }
  
  private static <U extends User> U setUserLevel(U user, int level) {
    U res = user;
    // 
    if (user == null) {
      return res;
    }
    if (StringUtils.isBlank(user.getUserId())) {
      return res;
    }
    int old_level = user.getLevel();
    boolean exec = false;
    try {
      user.setLevel(level);
      exec = execUpdateSql("updUserLevelByUserIdWithMap",res);
    } finally {
      if (!exec) {
        user.setLevel(old_level);
      }
    }
    return user;
  }
  
  
  
  public static <U extends User> boolean addUserBalance(U user, int deta) {
    boolean res = false;
    // 
    if (user == null) {
      return res;
    }
    if (StringUtils.isBlank(user.getUserId())) {
      return res;
    }
    Map<String, Object> param = new HashMap<String,Object>();
    param.put("userId", user.getUserId());
    param.put("balance", deta);
    res = execUpdateSql("updUserBalanceOpByUserIdWithMap",param);
    return res;
  }
  
  
  
  public static <U extends User> boolean addUserScore(U user, int deta) {
    boolean res = false;
    // 
    if (user == null) {
      return res;
    }
    if (StringUtils.isBlank(user.getUserId())) {
      return res;
    }
    Map<String, Object> param = new HashMap<String,Object>();
    param.put("userId", user.getUserId());
    param.put("score", deta);
    res = execUpdateSql("updUserScoreOpByUserIdWithMap",param);
    return res;
  }
  
  public static <U extends User> boolean userObtainPay3Free1Card(U user, int count){
    if(count>=0){
      return addUserPay3Free1Card(user, count);
    }else{
      return false;
    }
  }
  
  public static <U extends User> boolean userUsePay3Free1Card(U user){
    if(count>=0){
      return addUserPay3Free1Card(user, -1);
    }else{
      return false;
    }
  }
  
  protected static <U extends User> boolean addUserPay3Free1Card(U user, int count) {
    boolean res = false;
    // 
    if (user == null) {
      return res;
    }
    if (StringUtils.isBlank(user.getUserId())) {
      return res;
    }
    Map<String, Object> param = new HashMap<String,Object>();
    param.put("userId", user.getUserId());
    param.put("asset0", count);
    res = execUpdateSql("updUser3Free1OpByUserIdWithMap",param);
    return res;
  }
  
  public static <U extends User> boolean userObtainPay1Free1Card(U user, int count){
    if(count>=0){
      return addUserPay1Free1Card(user, count);
    }else{
      return false;
    }
  }
  
  public static <U extends User> boolean userUsePay1Free1Card(U user){
    if(count>=0){
      return addUserPay1Free1Card(user, -1);
    }else{
      return false;
    }
  }
  
  
  protected static <U extends User> boolean addUserPay1Free1Card(U user, int count) {
    boolean res = false;
    // 
    if (user == null) {
      return res;
    }
    if (StringUtils.isBlank(user.getUserId())) {
      return res;
    }
    
    Map<String, Object> param = new HashMap<String,Object>();
    param.put("userId", user.getUserId());
    param.put("asset1", count);
    res = execUpdateSql("updUser1Free1OpByUserIdWithMap",param);
    return res;
  }
  
  public static <U extends User> boolean userBuyL0toL1Card(U user) throws LevelUpCardIsNotNeedException, LevelUpCardIsNotNeedBuyExcption{
    boolean res = false;
    String id = user.getUserId();
    GegewuUser db_user = selectUserByOpenId(id);
    
    int level = db_user.getLevel();
    if(level>USER_LEVEL_0){
      throw new LevelUpCardIsNotNeedException();
    }
    if(db_user.getLevel0To1Cart()!=LEVEL_UP_CARD_STATUS_DEFAULT){
      throw new LevelUpCardIsNotNeedBuyExcption();
    }
    
    res = updateL0ToL1Card(id, LEVEL_UP_CARD_STATUS_OBTAINED);
    if(res){
      db_user = selectUserByOpenId(id);
      res = (db_user.getLevel0To1Cart()==LEVEL_UP_CARD_STATUS_OBTAINED);
    }
    return res;
  }
  
  public static <U extends User> boolean userUseL0toL1Card(U user) throws LevelUpCardHasBeenUsedException, NotHaveTargetLevelUpCardException{
    boolean res = false;
    
    String id = user.getUserId();
    GegewuUser db_user = selectUserByOpenId(id);
    int level = db_user.getLevel();
    if(level>USER_LEVEL_0||db_user.getLevel0To1Cart()==LEVEL_UP_CARD_STATUS_USED){
      throw new LevelUpCardHasBeenUsedException();
    }
    if(db_user.getLevel0To1Cart()!=LEVEL_UP_CARD_STATUS_OBTAINED){
      throw new NotHaveTargetLevelUpCardException();
    }
    
    updateL0ToL1Card(id, LEVEL_UP_CARD_STATUS_USED);
    setUserLevel(user, USER_LEVEL_1);

    db_user = selectUserByOpenId(id);
    res = (db_user.getLevel()==USER_LEVEL_1&&db_user.getLevel0To1Cart()==LEVEL_UP_CARD_STATUS_USED);
    return res;
  }
  
  public static <U extends User> boolean userBuyL1toL2Card(U user) throws LevelUpCardIsNotNeedException, LevelUpCardIsNotNeedBuyExcption{
    boolean res = false;
    String id = user.getUserId();
    GegewuUser db_user = selectUserByOpenId(id);
    
    int level = db_user.getLevel();
    if(level>USER_LEVEL_1){
      throw new LevelUpCardIsNotNeedException();
    }
    if(db_user.getLevel1To2Cart()!=LEVEL_UP_CARD_STATUS_DEFAULT){
      throw new LevelUpCardIsNotNeedBuyExcption();
    }
    
    res = updateL1ToL2Card(id, LEVEL_UP_CARD_STATUS_OBTAINED);
    if(res){
      db_user = selectUserByOpenId(id);
      res = (db_user.getLevel1To2Cart()==LEVEL_UP_CARD_STATUS_OBTAINED);
    }
    return res;
  }
  
  public static <U extends User> boolean userUseL1toL2Card(U user) throws LevelUpCardHasBeenUsedException, NotHaveTargetLevelUpCardException{
boolean res = false;
    
    String id = user.getUserId();
    GegewuUser db_user = selectUserByOpenId(id);
    int level = db_user.getLevel();
    if(level>USER_LEVEL_1||db_user.getLevel1To2Cart()==LEVEL_UP_CARD_STATUS_USED){
      throw new LevelUpCardHasBeenUsedException();
    }
    if(db_user.getLevel1To2Cart()!=LEVEL_UP_CARD_STATUS_OBTAINED){
      throw new NotHaveTargetLevelUpCardException();
    }
    
    updateL1ToL2Card(id, LEVEL_UP_CARD_STATUS_USED);
    setUserLevel(user, USER_LEVEL_2);

    db_user = selectUserByOpenId(id);
    res = (db_user.getLevel()==USER_LEVEL_2&&db_user.getLevel1To2Cart()==LEVEL_UP_CARD_STATUS_USED);
    return res;
  }
  
  public static <U extends User> boolean userBuyL2toL3Card(U user) throws LevelUpCardIsNotNeedException, LevelUpCardIsNotNeedBuyExcption{
    boolean res = false;
    String id = user.getUserId();
    GegewuUser db_user = selectUserByOpenId(id);
    
    int level = db_user.getLevel();
    if(level>USER_LEVEL_2){
      throw new LevelUpCardIsNotNeedException();
    }
    if(db_user.getLevel2To3Cart()!=LEVEL_UP_CARD_STATUS_DEFAULT){
      throw new LevelUpCardIsNotNeedBuyExcption();
    }
    
    res = updateL2ToL3Card(id, LEVEL_UP_CARD_STATUS_OBTAINED);
    if(res){
      db_user = selectUserByOpenId(id);
      res = (db_user.getLevel2To3Cart()==LEVEL_UP_CARD_STATUS_OBTAINED);
    }
    return res;
  }
  
  public static <U extends User> boolean userUseL2toL3Card(U user) throws LevelUpCardHasBeenUsedException, NotHaveTargetLevelUpCardException{
boolean res = false;
    
    String id = user.getUserId();
    GegewuUser db_user = selectUserByOpenId(id);
    int level = db_user.getLevel();
    if(level>USER_LEVEL_2||db_user.getLevel2To3Cart()==LEVEL_UP_CARD_STATUS_USED){
      throw new LevelUpCardHasBeenUsedException();
    }
    if(db_user.getLevel2To3Cart()!=LEVEL_UP_CARD_STATUS_OBTAINED){
      throw new NotHaveTargetLevelUpCardException();
    }
    
    updateL2ToL3Card(id, LEVEL_UP_CARD_STATUS_USED);
    setUserLevel(user, USER_LEVEL_3);

    db_user = selectUserByOpenId(id);
    res = (db_user.getLevel()==USER_LEVEL_3&&db_user.getLevel2To3Cart()==LEVEL_UP_CARD_STATUS_USED);
    return res;
  }
  
  public static <U extends User> boolean userBuyL3toL4Card(U user) throws LevelUpCardIsNotNeedException, LevelUpCardIsNotNeedBuyExcption{
    boolean res = false;
    String id = user.getUserId();
    GegewuUser db_user = selectUserByOpenId(id);
    
    int level = db_user.getLevel();
    if(level>USER_LEVEL_3){
      throw new LevelUpCardIsNotNeedException();
    }
    if(db_user.getLevel3To4Cart()!=LEVEL_UP_CARD_STATUS_DEFAULT){
      throw new LevelUpCardIsNotNeedBuyExcption();
    }
    
    res = updateL3ToL4Card(id, LEVEL_UP_CARD_STATUS_OBTAINED);
    if(res){
      db_user = selectUserByOpenId(id);
      res = (db_user.getLevel3To4Cart()==LEVEL_UP_CARD_STATUS_OBTAINED);
    }
    return res;
  }
  
  public static <U extends User> boolean userUseL3toL4Card(U user) throws LevelUpCardHasBeenUsedException, NotHaveTargetLevelUpCardException{
    boolean res = false;
    
    String id = user.getUserId();
    GegewuUser db_user = selectUserByOpenId(id);
    int level = db_user.getLevel();
    if(level>USER_LEVEL_3||db_user.getLevel3To4Cart()==LEVEL_UP_CARD_STATUS_USED){
      throw new LevelUpCardHasBeenUsedException();
    }
    if(db_user.getLevel3To4Cart()!=LEVEL_UP_CARD_STATUS_OBTAINED){
      throw new NotHaveTargetLevelUpCardException();
    }
    
    updateL3ToL4Card(id, LEVEL_UP_CARD_STATUS_USED);
    setUserLevel(user, USER_LEVEL_4);

    db_user = selectUserByOpenId(id);
    res = (db_user.getLevel()==USER_LEVEL_4&&db_user.getLevel3To4Cart()==LEVEL_UP_CARD_STATUS_USED);
    return res;
  }

  public static final int LEVEL_UP_CARD_STATUS_DEFAULT = 0;
  public static final int LEVEL_UP_CARD_STATUS_OBTAINED = 1;
  public static final int LEVEL_UP_CARD_STATUS_USED = 2;

  protected static boolean updateL0ToL1Card(String id, int status) {
    Map<String, Object> param = new HashMap<String,Object>();
    param.put("userId", id);
    param.put("asset2", status);
    return execUpdateSql("updUserLevel0to1OpByUserIdWithMap",param);
  }
  
  protected static boolean updateL1ToL2Card(String id, int status) {
    Map<String, Object> param = new HashMap<String,Object>();
    param.put("userId", id);
    param.put("asset3", status);
    return execUpdateSql("updUserLevel1to2OpByUserIdWithMap",param);
  }
  
  
  protected static <U extends User> boolean updateL2ToL3Card(String id, int status) {
    Map<String, Object> param = new HashMap<String,Object>();
    param.put("userId", id);
    param.put("asset4", status);
    return execUpdateSql("updUserLevel2to3OpByUserIdWithMap",param);
  }
  
  protected static boolean updateL3ToL4Card(String id, int status) {
    Map<String, Object> param = new HashMap<String,Object>();
    param.put("userId", id);
    param.put("asset5", status);
    return execUpdateSql("updUserLevel3to4OpByUserIdWithMap",param);
  }
  
  public static boolean addAddress(DefaultPostAddress address){
    boolean res = false;
    res = execUpdateSql("insAddress",address);
    return res ;
  }
  
  public static boolean setDefaultAdd(DefaultPostAddress address){
    boolean res = false;
    res = execUpdateSql("updDefaultAddressByOpenIdAddId",address);
    return res ;
  }
  

  
  public static Collection<DefaultPostAddress> selectAddressByOpenId(String openId){
    return execSelectList("selAddressByOpenId", openId);
  }

  /**
   * .
   * @author wangds 2016年8月8日 下午11:02:29.
   * @param address
   * @return
   */
  public static Boolean unuseAdd(DefaultPostAddress address) {
    boolean res = false;
    res = execUpdateSql("updAsUnuse",address);
    return res ;
  }

  /**
   * .
   * @author wangds 2016年8月11日 上午9:38:12.
   * @param param
   * @return
   */
  public static Boolean updateUserBaseInfo(Map<String, Object> param) {
    return execUpdateSql("updUserBaseInfoWithMap",param);
  }
  
  

}
